<?php

namespace App\Http\Controllers\Customer;

use App\Exports\CustomerBillExport;
use App\Exports\FixedExport;
use App\Http\Controllers\Admin\AirLine\Base\Flight;
use App\Http\Controllers\Controller;
use App\Http\Requests\Transport\OrderRequest;
use App\Models\FlightModel;
use App\Models\airline\base\RouteModel;
use App\Models\base\AccountModel;
use App\Models\base\WarehouseModel;
use App\Models\CustomerChargeModel;
use App\Models\finance\InvoiceModel;
use App\Models\finance\ReceivableGenericDetailModel;
use App\Models\finance\ReceivableGenericModel;
use App\Models\OrderModel;
use App\Models\OrderReceiveModel;
use App\Models\RecBillModel;
use App\Models\RecBillTicketModel;
use App\Models\TakeOrderModel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use App\Models\airline\base\FlightModel as BaseFlightModel;
use App\Models\base\CurrencyModel;
use App\Models\base\SubjectModel;
use App\Models\CountryModel;
use App\Models\DictionaryModel;
use App\Models\TakeOrderRecModel;
use Maatwebsite\Excel\Facades\Excel;

//账单列表
class Recbill extends Controller
{
    use OrderRequest;

    public function list(Request $request) {
        $page = $request->input('page', 1);
        $limit = $request->input('limit', 20);

        $query = (function($request) {
            $auth = $request->get('auth');
            $sn = trim($request->input('sn', ''));
            $start_time = trim($request->input('flight_start', ''));
            $end_time = trim($request->input('flight_end', ''));
            $customer_confirm = intval($request->input('customer_confirm', 0));


            $query = RecBillModel::query()
                ->where('customer_id', $auth->id)
                ->where('status', '>=', 4);

            if($sn) {
                $query->where('sn', 'like', "%{$sn}%");
            }
            if($start_time) { $query->where('start', '>=', $start_time); }
            if($end_time) { $query->where('end', '<=', $end_time); }
            if($customer_confirm) { $query->where('customer_confirm', $customer_confirm); }

            return $query;
        })($request);

        $total = $query->count('id');
        $items = $query
            ->offset(($page-1) * $limit)
            ->limit($limit)
            ->orderBy('id', 'desc')
            ->get();

        $list = $items->map(function($item) {

            $res = [
                'id' => $item->id,
                'sn' => $item->sn,
                'status' => $item->status,
                'start' => $item->start,
                'end' => $item->end,
                'amount' => $item->amount,
                'pay_amount' => $item->pay_amount,
                'pay_attachment' => $item->pay_attachment,
                'pay_remark' => $item->pay_remark,
                'customer_confirm' => $item->customer_confirm,
                'invoice_file' => $item->invoice_file,
            ];


            return $res;
        });

        return $this->success(['list' => $list, 'total' => $total]);
    }

    //确认账单
    public function confirm(Request $request){
        $ids = $request->input('ids', []);

        $find = RecBillModel::whereIn('id', $ids)->where('status', RecBillModel::BILL_WAIT_CONFIRM)->get();
        if(count($find) != count($ids)) {
            return $this->error('请选择未确认账单');
        }

        RecBillModel::whereIn('id', $ids)
            ->update([
                'customer_confirm' => 1,
                'status' => RecBillModel::BILL_CONFIRMED,
            ]);

        return $this->success();
    }

    //驳回账单
    public function reject(Request $request){
        $ids = $request->input('ids', []);
        $reason = $request->input('reason', '');

        $find = RecBillModel::whereIn('id', $ids)->where('status', RecBillModel::BILL_WAIT_CONFIRM)->get();
        if(count($find) != count($ids)) {
            return $this->error('请选择未确认账单');
        }

        RecBillModel::whereIn('id', $ids)
            ->update([
                'customer_confirm' => 2,
                'reject_reason' => $reason,
                'status' => RecBillModel::BILL_REJECTED,
            ]);


        return $this->success();
    }

    //付款
    public function pay(Request $request, $id){
        $auth = $request->get('auth');
        $params = $request->all();
        $validator = Validator::make($params, [
            'amount' => 'required|numeric|gt:0',
            'attachment' => 'required',
        ], [
            'amount.required' => '请输入金额',
            'amount.gt' => '金额必须大于0',
            'attachment.required' => '请上传附件'
        ]);
    
        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        $bill = RecBillModel::where('customer_id', $auth->id)->find($id);
        if(!$bill) {
            return $this->error('账单不存在');
        }


        if($bill->status != RecBillModel::BILL_CONFIRMED) {
            return $this->error('账单状态不正确');
        }

        $bill->status = RecBillModel::BILL_PAID;
        $bill->pay_amount = $params['amount'];
        $bill->pay_attachment = $params['attachment'];
        $bill->pay_remark = trim($params['remark'] ?? '');
        $bill->pay_at = date('Y-m-d H:i:s');
        $bill->save();

        return $this->success();

    }

    //详情
    public function detail(Request $request) {
        $id = $request->input('id');
        $rec_bill = RecBillModel::find($id);
        if (!$rec_bill) {
            return $this->error('数据不存在');
        }

        $receiv_take_orders = ReceivableGenericModel::with(['take_order', 'detail', 'flight'])->where('bill_id', $id)->get();

        $base_head = [
            ['label' => '提单号', 'prop' => 'take_order_sn'],
            ['label' => '货物属性', 'prop' => 'goods_attr'],
            ['label' => '航班日期', 'prop' => 'flight_date'],
            ['label' => '航班号', 'prop' => 'flight_number'],
            ['label' => '起运地', 'prop' => 'origin'],
            ['label' => '目的地', 'prop' => 'destination'],
            ['label' => '件数', 'prop' => 'package_num'],
            ['label' => '毛重', 'prop' => 'gross_weight'],
            ['label' => '体积重', 'prop' => 'volume_weight'],
            ['label' => '计费重', 'prop' => 'charging_weight'],
            ['label' => '空运单价', 'prop' => 'price'],
        ];

        $detail_name = [];
        foreach ($receiv_take_orders as $key => $value){
            if(count($value->detail)){
                $detail_name = array_merge($detail_name, $value->detail->pluck('name')->toArray());
            }
        }

        $detail_name = array_unique($detail_name);

        $detail_arr = [];
        foreach ($detail_name as $key => $value){
            $prop = 'fee' . $key;
            $base_head[] = [
                'label' => $value,
                'prop' => $prop
            ];
            $detail_arr[$value] = $prop;
        }

        $base_head[] = [
            'label' => '总金额',
            'prop' => 'total_amount'
        ];

        $list = $receiv_take_orders->map(function($item) use ($detail_arr) {
            $origin = $item->flight?->start_port_code;
            $destination = $item->flight?->arrive_port_code;

            $flight_number_id = $item->flight?->items?->first()->airline_flight_id ?? '';
            if(!$flight_number_id){
                $flight_number = '';
            }else{
                $flight_number = \App\Models\airline\base\FlightModel::where('id', $flight_number_id)->value('flight_number') ?? '';
            }

            $flight_date = $item->flight->take_off_time ? date('Y-m-d', strtotime($item->flight->take_off_time)) : '';

            $res = [
                'take_order_sn' => $item->take_order->sn ??  '',
                'goods_attr' => OrderModel::GOODS_ATTR_MAPS[$item->take_order->goods_attr ?? ''] ?? '',
                'flight_date' => $flight_date,
                'flight_number' => $flight_number,
                'origin' => $origin,
                'destination' => $destination,
                'package_num' => $item->package_num,
                'gross_weight' => $item->gross_weight,
                'volume_weight' => $item->volume_weight,
                'charging_weight' => $item->charging_weight,
                'price' => $item->air_freight_unit_price,
                'total_amount' => $item->detail->sum('amount') ?? 0,
            ];

            $item->detail->map(function($item2) use ($detail_arr, &$res) {
                $res[$detail_arr[$item2->name]] = $item2->amount;
            });

            return $res;
        });

        $res = [
            'head' => $base_head,
            'list' => $list
        ];
        return $this->success($res);
    }

    //提单详情
    public function take_order_detail(Request $request, $id) {
        $auth = $request->get('auth');
        $take_order = TakeOrderModel::where('customer_id', $auth->id)->find($id);
        if(!$take_order) {
            return $this->error('记录不存在');
        }

        $des = CountryModel::whereIn('id', $take_order->flight->items->pluck('destination_id'))
                ->pluck('name')->toArray();

        $routes = RouteModel::whereIn('id', $take_order->flight->items->pluck('route_id'))
            ->pluck('name')->toArray();

        $flight_no = BaseFlightModel::whereIn('id', $take_order->flight->items->pluck('airline_flight_id'))
            ->pluck('flight_number')->toArray();

        $detail = [
            'id' => $take_order->id,
            'sn' => $take_order->sn,
            'des_country' => implode(',', $des),
            'order_count' => $take_order->orders->count(),
            'storage_weight' => $take_order->orders->sum('storage_weight'),
            'reality_weight' => $take_order->reality_weight,
            'route' => implode(',', $routes),
            'take_off_time' => $take_order->flight->take_off_time ?? '',
            'flight_no' => implode(',', $flight_no),
            'orders' => $take_order->orders->map(function($order) {
                $packages_name = DictionaryModel::whereIn('id', explode(',', $order->packages))
                    ->pluck('name');
                return [
                    'id' => $order->id,
                    'sn' => $order->sn,
                    'big_pkgs' => $order->big_pkgs,
                    'pre_out_date' => $order->pre_out_date,
                    'des_country_name' => $order->airport->country_name ?? '',
                    'goods_attr_name' => OrderModel::GOODS_ATTR_MAPS[$order->goods_attr] ?? '',
                    'clearance_mode_name' => OrderModel::CLEARANCE_MODE_MAPS[$order->clearance_mode] ?? '',
                    'is_clearance' => $order->is_clearance,
                    'pre_volume' => $order->pre_volume,
                    'storage_weight' => $order->storage_weight,
                    'packages_name' => $packages_name,
                    'storage_time' => $order->storage_time,
                ];
            })
        ];



        $items = TakeOrderRecModel::where('take_order_id', $id)->get();
        $list = $items->map(function($item) {
            $name = TakeOrderRecModel::TYPE_MAPS[$item->type] ?? '';
            if($item->type == TakeOrderRecModel::TYPE_OTHER) {
                $subject = SubjectModel::find($item->subject_id);
                $name = '补录' . ($subject->name ?? '');
            }

            return [
                'id' => $item->id,
                'name' => $name,
                'currency' => $item->currency,
                'sys_amount' => $item->sys_amount,
                'amount' => $item->amount,
                'symbol' => $item->symbol,
                'create_user' => $item->create_admin->staff->name ?? '系统生成',
                'created_at' => $item->created_at->toDateTimeString(),
                'remark' => $item->remark,
                'is_sys' => $item->is_sys
            ];
        });

        $collect = [];
        foreach($list as $item) {
            if(isset($collect[$item['symbol']])) {
                $collect[$item['symbol']] += $item['amount'];
            } else {
                $collect[$item['symbol']] = $item['amount'];
            }
        }

        $result = '';
        foreach ($collect as $symbol => $value) {
            if (!empty($result)) {
                $result .= ", ";
            }
            $result .= $symbol . $value;
        }

        $detail['rcs'] = $list;

        return $this->success($detail);
    }

    //入仓单详情
    public function order_detail(Request $request, int $id){
        $auth = $request->get('auth');
        $order = OrderModel::withCount('split_order_addr')
            ->with([
                'split_order_addr'
            ])->find($id);
        if(!$order) {
            return $this->error('记录不存在');
        }

        $take_receive = OrderReceiveModel::where('order_id', $order->id)
            ->where('type', OrderReceiveModel::TAKE_TYPE)
            ->first();

        
        $packages_name = DictionaryModel::whereIn('id', explode(',', $order->packages))
            ->pluck('name');

        $res = [
            'id' => $order->id,
            'sn' => $order->sn,
            'take_order_no' => $order->take_order->sn ?? '',
            'pre_weight' => $order->pre_weight,
            'storage_weight' => $order->storage_weight,
            'split_order_addr_count' => $order->split_order_addr_count ?? 0,
            'status' => OrderModel::STATUS_MAPS[$order->status] ?? '',
            'pre_out_date' => $order->pre_out_date,
            'is_clearance' => $order->is_clearance,
            'des_country' => $order->airport->country_name ?? '',
            'des_city' => $order->des_city->name ?? '',
            'goods_attr' => OrderModel::GOODS_ATTR_MAPS[$order->goods_attr] ?? '',
            'clearance_mode' => OrderModel::CLEARANCE_MODE_MAPS[$order->clearance_mode] ?? '',
            'pre_volume' => $order->pre_volume,
            'packages' => $packages_name,
            'big_pkgs' => $order->big_pkgs,
            'small_pkgs' => $order->small_pkgs,
            'pre_time' => $order->pre_time,
            'confirm_time' => $order->confirm_time,
            'storage_time' => $order->storage_time,
            'outstock_time' => $order->outstock_time,
            'arrive_time' => $order->arrive_time,
            'signed_time' => $order->signed_time,
            'take_receive' => [
                'id' => $take_receive->id ?? '',
                'order_id' => $take_receive->order_id ?? '',
                'sn' => $take_receive->sn ?? '',
                'addr' => $take_receive->addr ?? '',
                'nums' => $order->big_pkgs ?? '',
                'goods_name' => $take_receive->goods_name ?? '',
                'weight' => $order->pre_weight ?? '',
                'remark' => $take_receive->remark ?? '',
            ],
            'split_order' => $order->split_order_addr ?? [],
        ];

        return $this->success($res);

        
        
    }

    //发票信息
    public function invoices(Request $request) {
        $auth = $request->get('auth');

        $list = InvoiceModel::where('customer_id', $auth->id)->get();

        return $this->success($list);
    }


    public function export(Request $request) {
        $id = $request->input('id');
        $rec_bill = RecBillModel::find($id);
        if (!$rec_bill) {
            return $this->error('数据不存在');
        }

        $receiv_take_orders = ReceivableGenericModel::with(['take_order', 'detail', 'flight'])->where('bill_id', $id)->get();

        $base_head = [
            '提单号',
            '货物属性',
            '航班日期',
            '航班号',
            '起运地',
            '目的地',
            '件数',
            '毛重',
            '体积重',
            '计费重',
        ];

        $detail = $receiv_take_orders->first()->detail;
        $detail_arr = [];
        foreach ($detail as $key => $value){
            $prop = 'fee' . $key;
            $base_head[] = $value->name;

            $detail_arr[$value->name] = $prop;
        }

        $list = $receiv_take_orders->map(function($item) use ($detail_arr) {
            $origin = $item->flight?->start_port_code;
            $destination = $item->flight?->arrive_port_code;

            $flight_number_id = $item->flight?->items?->first()->airline_flight_id ?? '';

            if(!$flight_number_id){
                $flight_number = '';
            }else{
                $flight_number = \App\Models\airline\base\FlightModel::where('id', $flight_number_id)->value('flight_number') ?? '';
            }

            $flight_date = $item->flight->take_off_time ? date('Y-m-d', strtotime($item->flight->take_off_time)) : '';

            $res = [
                'take_order_sn' => $item->take_order->sn ??  '',
                'goods_attr' => OrderModel::GOODS_ATTR_MAPS[$item->take_order->goods_attr ?? ''] ?? '',
                'flight_date' => $flight_date,
                'flight_number' => $flight_number,
                'origin' => $origin,
                'destination' => $destination,
                'package_num' => $item->package_num,
                'gross_weight' => $item->gross_weight,
                'volume_weight' => $item->volume_weight,
                'charging_weight' => $item->charging_weight,
            ];

            $item->detail->map(function($item2) use ($detail_arr, &$res) {
                $res[$detail_arr[$item2->name]] = $item2->amount;
            });

            return $res;
        });

        $file_name = '账单-'.date('Ymd').'.xlsx';

        return Excel::download(new CustomerBillExport($list, $base_head), $file_name);


    }

}
